<template>
  <div
    class="file-menu"
    :style="
      !getProps.isExpand ? 'width: calc(100% - 610px); float: left; padding-left: 10px' : 'width: calc(100% - 260px); float: left; padding-left: 10px'
    "
  >
    <BasicTable @register="registerTable" :rowClassName="getRowClassName" :rowSelection="rowSelection" @row-click="handleTableRowClick">
      <template #customTitle>
        <div v-if="selectedRowKeys.length > 1">
          <span>已选中{{ selectedRowKeys.length }}项</span>
          <span v-if="!isSearchRecycleBin" class="header-icon" @click="handleBatchMenuClick('download')">
            <a-tooltip>
              <template #title>批量下载</template>
              <span class="pointer header-icon-color app-iconify anticon pointer header-icon-color" style="font-size: 16px; display: inline-flex">
                <Icon icon="ant-design:cloud-download-outlined" />
              </span>
            </a-tooltip>
          </span>
          <span v-if="!isSearchRecycleBin" class="header-icon" @click="handleBatchMenuClick('move')">
            <a-tooltip>
              <template #title>批量移动</template>
              <span class="pointer header-icon-color app-iconify anticon pointer header-icon-color" style="font-size: 16px; display: inline-flex">
                <Icon icon="ant-design:swap-outlined" />
              </span>
            </a-tooltip>
          </span>
          <span v-if="!isSearchRecycleBin" class="header-icon" @click="handleBatchMenuClick('copy')">
            <a-tooltip>
              <template #title>批量复制</template>
              <span class="pointer header-icon-color app-iconify anticon pointer header-icon-color" style="font-size: 16px; display: inline-flex">
                <Icon icon="ant-design:copy-outlined" />
              </span>
            </a-tooltip>
          </span>
          <span v-if="!isSearchRecycleBin" class="header-icon" @click="handleBatchMenuClick('del')">
            <a-tooltip>
              <template #title>批量删除</template>
              <span class="pointer header-icon-color app-iconify anticon pointer header-icon-color" style="font-size: 16px; display: inline-flex">
                <Icon icon="ant-design:delete-outlined" />
              </span>
            </a-tooltip>
          </span>
          <span v-if="isSearchRecycleBin" class="header-icon" @click="handleBatchMenuClick('cdel')">
            <a-tooltip>
              <template #title>批量彻底删除</template>
              <span class="pointer header-icon-color app-iconify anticon pointer header-icon-color" style="font-size: 16px; display: inline-flex">
                <Icon icon="ant-design:delete-filled" />
              </span>
            </a-tooltip>
          </span>
          <span v-if="isSearchRecycleBin" class="header-icon" @click="handleBatchMenuClick('recycle')">
            <a-tooltip>
              <template #title>批量还原</template>
              <span class="pointer header-icon-color app-iconify anticon pointer header-icon-color" style="font-size: 16px; display: inline-flex">
                <Icon icon="ant-design:rollback-outlined" />
              </span>
            </a-tooltip>
          </span>
        </div>
        <div v-else>
          <span> 文件名称 </span>
        </div>
      </template>
      <template #fileName="{ record, column }">
        <div class="editable-cell">
          <a-input
            v-if="record.id === editingKey"
            ref="editingInputRef"
            v-model:value="record.fileName"
            :max-length="50"
            @blur="handleAddFolderBlur(record)"
            @focus="handleAddFolderFocus"
          />
          <div v-else class="editable-cell-text-wrapper">
            <div class="pointer" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
              <img v-if="record.fileType == 'image'" class="file-image" :src="record.url" :preview="false" />
              <img
                v-else-if="getFileTypeIcon(record.fileName, record.fileType).useImage"
                class="file-image"
                :src="getFileTypeIcon(record.fileName, record.fileType).image"
                :preview="false"
              />
              <a-icon
                v-else
                :icon="getFileTypeIcon(record.fileName, record.fileType).icon"
                class="file-icon"
                :style="getFileTypeIcon(record.fileName, record.fileType).style + 'margin-left: 2px; margin-top:0px; width: 23px;font-size:24px;'"
              />
              <span
                class="file-text"
                :style="record.fileType == 'image' ? 'margin-left: 8px' : 'margin-left: 28px'"
                @click.stop="handleFileClick(record)"
              >
                {{ record.fileName }}
              </span>
            </div>
            <div class="editable-cell-icon">
              <Icon
                icon="ant-design:share-alt-outlined"
                class="header-icon-color pointer"
                style="font-size: 16px; display: inline-flex; top: -6px"
                @click="handleFileShareClick(record)"
              />
              <Icon
                icon="ant-design:cloud-download-outlined"
                class="header-icon-color pointer"
                style="font-size: 16px; display: inline-flex; top: -6px; left: 10px"
                @click="handleFileDownloadClick(record)"
              />
              <a-dropdown :trigger="['click']">
                <Icon
                  icon="ant-design:ellipsis-outlined"
                  class="header-icon-color pointer"
                  style="font-size: 16px; display: inline-flex; top: -6px; left: 20px"
                />
                <template #overlay>
                  <a-menu class="menu-more">
                    <template v-for="item in fileMenu(record)">
                      <a-menu-divider v-if="item.value == 'divider'" :key="item.value" />
                      <a-menu-item v-else :key="item.value" @click.stop="handleFileMenuClick(item.value, record)">
                        <Icon :icon="item.icon" class="table-icon-color pointer" style="font-size: 16px; display: inline-flex" />
                        <span class="table-font-size">{{ item.label }}</span>
                      </a-menu-item>
                    </template>
                  </a-menu>
                </template>
              </a-dropdown>
            </div>
          </div>
        </div>
      </template>
    </BasicTable>
    <FolderSelectModal ref="folderSelectMoveRef" @success="setMoveFolder" />
    <FolderSelectModal ref="folderSelectCopyRef" @success="setCopyFolder" />
    <FileLinkModal ref="fileLinkEditRef" @success="reloadData" />
    <FileShareModal ref="fileShareRef" />
  </div>
</template>

<script lang="ts">
  import { defineComponent, ref, unref, nextTick, computed } from 'vue';
  import { BasicTable } from '/@/components/Table';
  import { useListPage } from '/@/hooks/system/useListPage';
  import { cloneDeep } from 'lodash-es';
  import { buildUUID } from '/@/utils/uuid';
  import { useGlobSetting } from '/@/hooks/setting';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
  import { downloadByUrl } from '/@/utils/file/download';
  import FolderSelectModal from './FolderSelectModal.vue';
  import FileLinkModal from './FileLinkModal.vue';
  import FileShareModal from './FileShareModal.vue';
  import {
    getFileList,
    saveOrUpdate,
    deleteFile,
    batchDeleteFile,
    changeStar,
    downLoadFiles,
    copyFiles,
    moveFiles,
    renameFile,
    putRecycleBin,
    deleteRecycleBin,
    incrDownCount,
    incrReadCount,
  } from '../files.api';
  import { columns, getFileTypeIcon, fileMenu } from '../files.data';
  import { getToken } from '/@/utils/auth';

  export default defineComponent({
    name: 'RightFile',
    components: { BasicTable, FolderSelectModal, FileLinkModal, FileShareModal },
    props: {
      isExpand: { type: Boolean, default: true },
    },
    emits: ['rowClick', 'changeFolder', 'openFileAttribute'],
    setup(props, { emit }) {
      const glob = useGlobSetting();

      const folderSelectMoveRef = ref();
      const folderSelectCopyRef = ref();
      const fileLinkEditRef = ref();
      const fileShareRef = ref();
      const editingInputRef = ref();

      // 文件搜索条件
      const searchParams = { type: null, keyword: null, parentId: null };
      // 是否查询回收站数据
      const isSearchRecycleBin = ref(false);
      // 移动或复制的ID
      const moveOrCopyKeys = ref();
      // 列表中编辑KEY
      const editingKey = ref('');
      const addKeyPrix = 'sysfiles_';
      // 目录路径
      const folderPathList: any = ref([]);
      // 选中行号
      const lastClickRowId = ref('');

      const { createMessage: $message } = useMessage();

      const getProps = computed((): Recordable => {
        const opt = {
          ...props,
        };
        return {
          ...opt,
        };
      });

      // 列表页面公共参数、方法
      const { tableContext } = useListPage({
        designScope: 'sys-files-template',
        tableProps: {
          // title: '文件列表',
          // titleHelpMessage: ['可对目录与文件操作'],
          api: getFileList,
          columns: columns,
          useSearchForm: false,
          showIndexColumn: false,
          showTableSetting: false,
          showActionColumn: false,
          bordered: false,
          inset: false,
          size: 'small',
          clickToRowSelect: false,
          rowSelection: {
            type: 'checkbox',
          },
          // formConfig: {
          //   schemas: searchFormSchema,
          //   fieldMapToTime: [['fieldTime', ['beginDate', 'endDate'], 'YYYY-MM-DD HH:mm:ss']],
          // },
          // actionColumn: {
          //   width: 150,
          //   fixed: 'right',
          // },
          // 请求之前对参数做处理
          beforeFetch(params) {
            params.type = searchParams.type;
            params.keyword = searchParams.keyword;
            params.storeType = 'manage';
            params.parentId = searchParams.parentId;
            params.isRecycleBin = isSearchRecycleBin.value;
          },
        },
      });
      const [
        registerTable,
        { reload, getDataSource, getRawDataSource, setTableData, clearSelectedRowKeys, setSelectedRowKeys },
        { rowSelection, selectedRowKeys, selectedRows },
      ] = tableContext;

      /**
       * 自定义选中行:点击行
       */
      function getRowClassName(record: any, index: number) {
        //console.log('getRowClassName', record.id == lastClickRowId.value);
        return record.id == lastClickRowId.value ? 'ant-table-row-selected' : '';
      }

      /**
       * 表格-多选工具栏
       */
      async function handleBatchMenuClick(key) {
        const pathList = cloneDeep(folderPathList.value);
        const fileIds = selectedRowKeys.value.join(',');
        switch (key) {
          case 'download':
            const zipName = folderPathList.value[folderPathList.value.length - 1].fileName;
            downloadZip(zipName, fileIds);
            break;
          case 'move':
            moveOrCopyKeys.value = fileIds;
            folderSelectMoveRef.value.showModal('移动到', pathList, fileIds);
            break;
          case 'copy':
            moveOrCopyKeys.value = fileIds;
            folderSelectCopyRef.value.showModal('复制到', pathList, fileIds);
            break;
          case 'del':
            batchDeleteFile({ fileIds: fileIds }, reloadData);
            break;
          case 'cdel':
            deleteRecycleBin({ fileIds: fileIds }, reloadData);
            break;
          case 'recycle':
            putRecycleBin({ fileIds: fileIds }, reloadData);
            break;
        }
      }

      /**
       * 表格-文件夹或文件下拉菜单事件
       */
      async function handleFileMenuClick(key, record) {
        const pathList = cloneDeep(folderPathList.value);
        switch (key) {
          case 'rollback':
            putRecycleBin({ fileIds: record.id }, reloadData);
            break;
          case 'cdel':
            deleteRecycleBin({ fileIds: record.id }, reloadData);
            break;
          case 'edit':
            fileLinkEditRef.value.showUpateModal(record);
            break;
          case 'star':
            const starFlag = record.isStar == '1' ? '0' : '1';
            const params = { fileId: record.id, isStar: starFlag };
            await changeStar(params, function () {
              record.isStar = starFlag;
            });
            break;
          case 'rename':
            editingKey.value = record.id;
            nextTick(() => {
              editingInputRef.value.focus();
            });
            break;
          case 'upload':
            break;
          case 'swap':
            moveOrCopyKeys.value = record.id;
            folderSelectMoveRef.value.showModal('移动到', pathList, record.id);
            break;
          case 'copy':
            moveOrCopyKeys.value = record.id;
            folderSelectCopyRef.value.showModal('复制到', pathList, record.id);
            break;
          case 'del':
            deleteFile(
              {
                id: record.id,
              },
              reloadData
            );
            break;
          case 'setting':
            emit('openFileAttribute', record);
            break;
        }
      }

      /**
       * 表格-数据行-文件名称点击事件
       */
      async function handleFileClick(record) {
        if (record.isFolder == '1') {
          // 目录时，进入下一层
          folderPathList.value.push({
            fileId: record.id,
            fileName: record.fileName,
          });
          searchParams.parentId = record.id;
          lastClickRowId.value = '';
          const pathList = cloneDeep(folderPathList.value);
          reloadData();
          emit('changeFolder', record, pathList);
        } else {
          // 文件时
          const index = record.fileName.lastIndexOf('.');
          const suffix = record.fileName.substring(index + 1);
          if ('url' == suffix) {
            window.open(record.url);
          } else {
            const previewurl = `${glob.viewUrl}?url=` + encodeURIComponent(record.url);
            window.open(previewurl);
          }
          incrReadCount({ fileIds: record.id });
        }
      }

      /**
       * 表格-数据行-分享点击事件
       */
      async function handleFileShareClick(record) {
        fileShareRef.value.showModal(record);
      }

      /**
       * 表格-数据行-下载点击事件
       */
      async function handleFileDownloadClick(record) {
        if (record.enableDown == '0') {
          return;
        }
        if (record.isFolder == '1') {
          const zipName = folderPathList.value[folderPathList.value.length - 1].fileName;
          downloadZip(zipName, record.id);
        } else {
          downloadFile(record.url);
          incrDownCount({ fileIds: record.id });
        }
      }

      /**
       * 表格-数据行-单击事件
       */
      async function handleTableRowClick(record, index) {
        // setSelectedRowKeys([record.id]);
        lastClickRowId.value = record.id;
        emit('rowClick', record);
      }

      /**
       * 表格-新建文件夹-输入框失获得焦点事件
       */
      async function handleAddFolderFocus(e) {
        e.target.select();
      }

      /**
       * 表格-新建文件夹-输入框失去焦点事件
       */
      async function handleAddFolderBlur(record) {
        editingKey.value = '';
        const isUpdateData = record.id?.indexOf(addKeyPrix) == -1;
        if (isUpdateData) {
          // 更新目录名称
          await renameFile({
            fileId: record.id,
            fileName: record.fileName,
            type: 'rename',
          });
          reloadData();
        } else if (record.fileName?.length > 0) {
          // 添加新目录名称
          const folderItem = folderPathList.value[folderPathList.value.length - 1];
          const parentId = folderItem.fileId;
          await saveOrUpdate(
            {
              delFlag: '0',
              fileName: record.fileName,
              fileType: 'folder',
              isFolder: '1',
              parentId: parentId,
              storeType: 'manage',
            },
            false
          );
          reloadData();
        } else {
          $message.warn('文件名称不能为空');
          const data = getDataSource();
          let index = data.findIndex((p) => {
            return p.id == record.id;
          });
          data.splice(index, 1);
          setTableData(data);
        }
      }

      /**
       * 移动到指定目录回调事件
       */
      async function setMoveFolder(pathList) {
        const folderItem = pathList[pathList.length - 1];
        const parentId = folderItem.fileId;
        await moveFiles({
          fileIds: moveOrCopyKeys.value,
          moveToFileId: parentId,
        });
        reloadData();
      }

      /**
       * 复制到指定目录回调事件
       */
      async function setCopyFolder(pathList) {
        const folderItem = pathList[pathList.length - 1];
        const parentId = folderItem.fileId;
        await copyFiles({
          fileIds: moveOrCopyKeys.value,
          copyToFileId: parentId,
        });
        reloadData();
      }

      /**
       * 重新加载数据
       */
      async function reloadData() {
        clearSelectedRowKeys();
        reload();
      }

      /**
       * 下载压缩文件
       */
      async function downloadZip(zipName, fileIds) {
        //const token = getToken();
        //let url = `${glob.domainUrl}` + downLoadFiles + '?fileIds=' + fileIds + '&zipName=' + encodeURIComponent(zipName) + '&access_token=' + token;
        //url = getFileAccessHttpUrl(url);

        // downloadByUrl({
        //   url: url,
        //   target: '_self',
        // });
        downLoadFiles({ fileIds: fileIds, zipName: zipName });
      }

      /**
       * 下载文件
       */
      async function downloadFile(url) {
        url = getFileAccessHttpUrl(url);

        downloadByUrl({
          url: url,
          target: '_self',
        });
      }

      /**
       * 加载表格数据
       * type： used 最近使用文件, star 标星文件, 其他根据fileId查询
       * keyword： 搜索关键字
       * fileId：目录ID
       * fileName: 目录名称
       * isRecycleBin：是否为回收站数据
       */
      function loadRootFloderData(type, keyword, fileId, fileName, isRecycleBin) {
        if (fileId) {
          folderPathList.value = [
            {
              fileId: fileId,
              fileName: fileName,
            },
          ];
        } else {
          folderPathList.value = [];
        }
        searchParams.type = type;
        searchParams.parentId = fileId;
        searchParams.keyword = keyword;
        isSearchRecycleBin.value = isRecycleBin;
        reloadData();
      }

      /**
       * 创建目录
       */
      function createFolder() {
        editingKey.value = addKeyPrix + buildUUID();
        nextTick(() => {
          editingInputRef.value.focus();
        });
        const data = getDataSource();
        data.unshift({ id: editingKey.value, fileName: '' });
        setTableData(data);
      }

      return {
        getProps,
        registerTable,
        folderSelectMoveRef,
        folderSelectCopyRef,
        fileLinkEditRef,
        fileShareRef,
        editingInputRef,
        getFileTypeIcon,
        rowSelection,
        selectedRowKeys,
        fileMenu,
        editingKey,
        isSearchRecycleBin,
        handleBatchMenuClick,
        handleFileClick,
        handleFileShareClick,
        handleFileDownloadClick,
        handleTableRowClick,
        handleAddFolderFocus,
        handleAddFolderBlur,
        handleFileMenuClick,
        getRowClassName,
        setMoveFolder,
        setCopyFolder,
        reloadData,
        loadRootFloderData,
        createFolder,
      };
    },
  });
</script>

<style lang="less" scoped>
  @import '../less/RightFile';
</style>
